package com.spagettikod.t437.component;

import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.TableColumn;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.spagettikod.t437.T437;
import com.spagettikod.t437.simpledb.SimpleDBAttribute;
import com.spagettikod.t437.simpledb.SimpleDBDomain;

public class SimpleDBJTable extends JTable {
	private static final long serialVersionUID = 2741534052269090471L;

	private static final Log log = LogFactory.getLog(SimpleDBJTable.class);

	private SimpleDBDomain domain;

	public SimpleDBJTable() {
		super();
		setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//		setRowSelectionAllowed(false);
		setCellSelectionEnabled(true);
		setAutoResizeMode(AUTO_RESIZE_OFF);
		setAutoCreateRowSorter(true);
		setDefaultRenderer(SimpleDBAttribute.class, new SimpleDBAttributeTableCellRenderer());
	}

	public void clearTable() {
		domain.reset();
	}

	public void setDomain(SimpleDBDomain sdbDomain) {
		domain = sdbDomain;
		domain.reset();
		if (log.isDebugEnabled()) {
			log
					.debug("Setting domain " + domain
							+ ", creating new table model");
		}
		SimpleDBTableModel model = new SimpleDBTableModel(domain);
		setModel(model);
		model.fireTableStructureChanged();
	}

	/**
	 * Calculates number of rows that are visible for the current table size.
	 * 
	 * @return number of visible rows.
	 */
	public int getVisibleRows() {
		Float rows = new Float(
				T437.getApplicationFrame().getSize().height - 100)
				/ new Float(getRowHeight());
		return Math.round(rows.floatValue());
	}

	public void executeQuery(String query) {
		domain.fetchData(query, getVisibleRows());
		((SimpleDBTableModel) getModel()).fireTableStructureChanged();
		fitColumnWidthsToContent();
	}

	public void fetchAllRows(String query) {
		domain.fetchData(query);
		((SimpleDBTableModel) getModel()).fireTableStructureChanged();
		fitColumnWidthsToContent();
	}

	/**
	 * Sets the width of each column to fit the longest item. Reads all rows for
	 * each column and sets the width so the longest item fits in the column.
	 */
	public void fitColumnWidthsToContent() {
		for (int col = 0; col < getModel().getColumnCount(); col++) {
			TableColumn tblColumn = getColumnModel().getColumn(col);
			int width = tblColumn.getPreferredWidth();
			for (int row = 0; row < getModel().getRowCount(); row++) {
				JLabel l = (JLabel) getCellRenderer(row, col)
						.getTableCellRendererComponent(this,
								getValueAt(row, col), false, false, row, col);
				int newWidth = getIntercellSpacing().width
						+ l.getPreferredSize().width;
				width = Math.max(width, newWidth);
			}
			tblColumn.setPreferredWidth(width);
		}
	}
}